//http://poj.org/problem?id=3468
//线段树+懒标记
//注意下放标记时要用加法，不是直接赋值
#include<stdio.h>
#include<algorithm>
#include<string>
#include<iostream>
using namespace std;
#define ll long long
const int MAXN=1e5+7;
struct node
{
    int l,r;
    ll sum,lazy;
}tr[MAXN*4];
ll a[MAXN];
inline void pushup(int n){
    tr[n].sum=tr[n<<1].sum+tr[n<<1|1].sum;
    return;
}
inline void pushdown(int n){
    if(tr[n].lazy){
        tr[n<<1].sum+=(tr[n<<1].r-tr[n<<1].l+1)*tr[n].lazy;
        tr[n<<1|1].sum+=(tr[n<<1|1].r-tr[n<<1|1].l+1)*tr[n].lazy;
        tr[n<<1].lazy+=tr[n].lazy;
        tr[n<<1|1].lazy+=tr[n].lazy;
        tr[n].lazy=0;
    }
}
void build(int n,int l,int r){
    tr[n].l=l,tr[n].r=r,tr[n].lazy=0;
    if(l==r){
        tr[n].sum=(ll)a[l];
        return;
    }
    int mid=l+r>>1;
    build(n<<1,l,mid);
    build(n<<1|1,mid+1,r);
    pushup(n);
    return;
}
void add(int n,int l ,int r,ll k){
    if(tr[n].l>r||tr[n].r<l) return;
    if(tr[n].l>=l&&tr[n].r<=r){
        tr[n].sum+=(tr[n].r-tr[n].l+1)*k;
        tr[n].lazy+=k;
        return;
    }
    pushdown(n);
    int mid=tr[n].l+tr[n].r>>1;
    if(mid>=l) add(n<<1,l,r,k);
    if(mid<r) add(n<<1|1,l,r,k);
    pushup(n);
    return;
}
ll query(int n,int l,int r){
    if(tr[n].l>r||tr[n].r<l) return 0;
    if(tr[n].l>=l&&tr[n].r<=r) return tr[n].sum;
    pushdown(n);
    return query(n<<1,l,r)+query(n<<1|1,l,r);
}
int main(){
    int n,t;
    scanf("%d%d",&n,&t);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    build(1,1,n);
    while(t--){
        char c[5];
        int x,y;
        scanf("%s%d%d",c,&x,&y);
        if(c[0]=='Q'){
            printf("%lld\n",query(1,x,y));
        }
        else{
            ll k;
            scanf("%lld",&k);
            add(1,x,y,k);
        }
    }
    return 0;
}